home *** CD-ROM | disk | FTP | other *** search
/ Workbench Add-On / Workbench Add-On - Volume 1.iso / BBS-Archive / Util / Workbench / lupe.lha / source / lupe.c next >
C/C++ Source or Header  |  1995-07-18  |  13KB  |  513 lines

  1. // Lupe V1.0 - June 1995 - © Frank Toepper
  2. // a simple lens
  3. // AmigaOS 3.0
  4.  
  5. #include <intuition/intuition.h>
  6. #include <intuition/imageclass.h>
  7. #include <intuition/icclass.h>
  8. #include <intuition/gadgetclass.h>
  9. #include <exec/exec.h>
  10. #include <dos/dos.h>
  11. #include <graphics/scale.h>
  12. #include <devices/inputevent.h>
  13. #include <libraries/commodities.h>
  14. #include <libraries/gadtools.h>
  15. #include <graphics/displayinfo.h>
  16. #include <graphics/gfxmacros.h>
  17. #include <clib/intuition_protos.h>
  18. #include <clib/graphics_protos.h>
  19. #include <clib/exec_protos.h>
  20. #include <clib/commodities_protos.h>
  21. #include <clib/gadtools_protos.h>
  22. #include <wbstartup.h>
  23.  
  24. #pragma header
  25.  
  26. #define MAXSCALEFAC 20
  27.  
  28. ULONG innerwidth = 200, innerheight = 100, scalefac = MAXSCALEFAC / 2;
  29. ULONG cxsigflag, scrdepth;
  30. LONG waitmask = 0;
  31. UWORD leftoff, topoff, bottomoff, rightoff;
  32. WORD sizeiw, sizeih, winx, winy, winleft = 0, wintop;
  33. BYTE timesig;
  34. APTR VisualInfo;
  35. struct MsgPort *broker_mp, *userport;
  36. struct Task *thistask;
  37. struct Window *mywin = NULL;
  38. struct Screen *scr = NULL;
  39. struct Menu *menu;
  40. struct MenuItem *item;
  41. struct BitMap *srcbm = NULL, *destbm = NULL, *scrbm;
  42. BOOL hires, newlook, jump = FALSE, mm = TRUE;
  43. CxObj *broker, *customcxobj;
  44. Object *propgadget;
  45. char pubscreenname[MAXPUBSCREENNAME];
  46. struct Library *CxBase, *GfxBase, *GadToolsBase;
  47.  
  48. extern struct ExecBase *SysBase;
  49.  
  50. BOOL jumpFunc ();
  51. BOOL mmFunc ();
  52. BOOL AboutFunc ();
  53. BOOL QuitFunc ();
  54.  
  55. struct EasyStruct es_about = {
  56.    20, 0,
  57.    "Lupe",
  58.    "%s%s%s\n\n%s\n%s\n%s\n%s\n%s\n%s\n\n%s\n%s\n\n%s",
  59.    "%s"
  60. };
  61.  
  62. char *era_about[] = {
  63.    "Lupe V1.0 (", __DATE__, ")",
  64.    "written by:",
  65.    "  Frank Toepper",
  66.    "  Maxim Gorki Strasse 5A",
  67.    "  Greifswald",
  68.    "  17491",
  69.    "  GERMANY",
  70.    "EMail:",
  71.    "  toepper@rz.uni-greifswald.de",
  72.    "This program is Public Domain",
  73.    "Ok"
  74. };
  75.  
  76. struct NewBroker newbroker = {
  77.    NB_VERSION,
  78.    "Lupe",
  79.    "Lupe V1.0",
  80.    "A Simple Lens",
  81.    3,
  82.    0,
  83.    0,
  84.    NULL,
  85.    0
  86. };
  87.  
  88. struct BitScaleArgs bsa = {
  89.    // Src Koords
  90.    0, 0,
  91.    innerwidth / scalefac,
  92.    innerheight / scalefac,
  93.    // Src Faktoren
  94.    1, 1,
  95.    0, 0,
  96.    innerwidth,
  97.    innerheight,
  98.    // Dest Faktoren
  99.    scalefac, scalefac,
  100.    // Bitmaps
  101.    NULL, NULL,
  102.    0,
  103.    0, 0,
  104.    0, 0
  105. };
  106.  
  107. int setupscreen ()
  108. {
  109. struct Screen *tmpscr;
  110.  
  111.    if (scr)
  112.    {
  113.       if (NextPubScreen (scr, pubscreenname))
  114.       {
  115.          if ((tmpscr = LockPubScreen (pubscreenname)) != scr)
  116.          {
  117.             FreeVisualInfo (VisualInfo);
  118.             UnlockPubScreen (NULL, scr);
  119.             scr = tmpscr;
  120.          }
  121.          else return 1;
  122.       }
  123.    }
  124.    else if (!(scr = LockPubScreen (NULL))) return 2;
  125.    if (!(VisualInfo = GetVisualInfoA (scr, NULL))) return 3;
  126.    return 0L;
  127. }
  128.  
  129. void CloseDownScreen ()
  130. {
  131.    if (VisualInfo)
  132.    {
  133.       FreeVisualInfo (VisualInfo);
  134.       VisualInfo = NULL;
  135.    }
  136.    if (scr)
  137.    {
  138.       UnlockPubScreen (NULL, scr);
  139.       scr = NULL;
  140.    }
  141. }
  142.  
  143. void getoffsets ()
  144. {
  145. struct DrawInfo *drawinfo;
  146. APTR sizeobject;
  147. ULONG attr;
  148.    
  149.    hires = !(scr->Flags & SCREENHIRES);
  150.    hires ? (rightoff = 18) : (rightoff = 13);
  151.    if (drawinfo = GetScreenDrawInfo (scr))
  152.    {
  153.       if (sizeobject = NewObject (NULL, SYSICLASS,
  154.        SYSIA_Which, SIZEIMAGE,
  155.        SYSIA_DrawInfo, drawinfo,
  156.        SYSIA_Size, hires ? SYSISIZE_HIRES : SYSISIZE_MEDRES))
  157.       {
  158.          if (GetAttr (IA_Width, sizeobject, &attr))
  159.          {
  160.             sizeiw = attr;
  161.             rightoff =  (UWORD) attr;
  162.          }
  163.          if (GetAttr (IA_Height, sizeobject, &attr))
  164.          {
  165.             sizeih = attr;
  166.          }
  167.          newlook = (drawinfo->dri_Flags & DRIF_NEWLOOK) && (drawinfo->dri_Depth != 1);
  168.          DisposeObject (sizeobject);
  169.       }
  170.       FreeScreenDrawInfo (scr, drawinfo);
  171.    }
  172.    topoff = scr->RastPort.TxHeight + (UWORD) scr->WBorTop + 1;
  173.    leftoff = scr->WBorLeft;
  174.    bottomoff = scr->WBorBottom;
  175.    scrbm = &scr->BitMap;
  176.    scrdepth = scr->BitMap.Depth;
  177. }
  178.  
  179. int allocbm ()
  180. {
  181.    if (destbm) FreeBitMap (destbm);
  182.    if (srcbm) FreeBitMap (srcbm);
  183.    winx = mywin->Width;
  184.    winy = mywin->Height;
  185.    innerwidth = winx - (leftoff + rightoff);
  186.    innerheight = winy - (topoff + bottomoff);
  187.    if (!(srcbm = AllocBitMap (innerwidth / scalefac, innerheight / scalefac, scrdepth, BMF_CLEAR, scrbm)))
  188.       return 1;
  189.    if (!(destbm = AllocBitMap (innerwidth, innerheight, scrdepth, BMF_CLEAR, scrbm)))
  190.       return 2;
  191.    bsa.bsa_SrcWidth = innerwidth / scalefac;
  192.    bsa.bsa_SrcHeight = innerheight / scalefac;
  193.    bsa.bsa_DestWidth = innerwidth;
  194.    bsa.bsa_DestHeight = innerheight;
  195.    bsa.bsa_SrcBitMap = srcbm;
  196.    bsa.bsa_DestBitMap = destbm;
  197.    bsa.bsa_XDestFactor = bsa.bsa_YDestFactor = scalefac;
  198.    return 0;
  199. }
  200.  
  201. BOOL openwin ()
  202. {
  203. WORD bw, rh;
  204. struct Rectangle zoom = {
  205.    60 + leftoff + rightoff,
  206.    30 + topoff + bottomoff + sizeih,
  207.    -1, -1
  208. };
  209. struct NewMenu newmenu[] = {
  210.    { NM_TITLE, "Project",   0, 0, 0, 0, },
  211.    {  NM_ITEM, "Jump",      "J", 0, 0, jumpFunc, },
  212.    {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
  213.    {  NM_ITEM, "MouseMove", "M", (mm ? CHECKED : 0) | CHECKIT, 0, mmFunc, },
  214.    {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
  215.    {  NM_ITEM, "About",     "A", 0, 0, AboutFunc, },
  216.    {  NM_ITEM, NM_BARLABEL, 0, 0, 0, 0, },
  217.    {  NM_ITEM, "Quit",      "Q", 0, 0, QuitFunc, },
  218. };
  219.  
  220.    if (hires) bw = rh = 2;
  221.    else bw = rh = 1;
  222.    if (menu = CreateMenusA (newmenu, NULL))
  223.    {
  224.       if (LayoutMenus (menu, VisualInfo, GTMN_NewLookMenus, TRUE, TAG_DONE))
  225.       {
  226.          if (propgadget = (Object *) NewObject (NULL, PROPGCLASS,
  227.           PGA_Freedom,     FREEVERT,
  228.           ICA_TARGET,      ICTARGET_IDCMP,
  229.           PGA_NewLook,     TRUE,
  230.           PGA_Borderless,  newlook,
  231.           PGA_Total,       MAXSCALEFAC,
  232.           PGA_Visible,     1,
  233.           PGA_Top,         scalefac,
  234.           GA_RelVerify,    1,
  235.           GA_RelRight,     bw - sizeiw + 3,
  236.           GA_Top,          topoff + rh,
  237.           GA_Width,        sizeiw - bw - bw - 4,
  238.           GA_RelHeight,    -topoff - sizeih - rh - rh,
  239.           GA_RightBorder,  TRUE,
  240.           TAG_DONE))
  241.          {
  242.             if (mywin = OpenWindowTags (NULL,
  243.              WA_Activate,       1,
  244.              WA_CloseGadget,    1,
  245.              WA_DepthGadget,    1,
  246.              WA_DragBar,        1,
  247.              WA_SizeBRight,     1,
  248.              WA_SizeGadget,     1,
  249.              WA_AutoAdjust,     1,
  250.              WA_SimpleRefresh,  1,
  251.              WA_ReportMouse,    1,
  252.              WA_NewLookMenus,   1,
  253.              WA_MaxHeight,      -1,
  254.              WA_MaxWidth,       -1,
  255.              WA_MinHeight,      30 + topoff + bottomoff,
  256.              WA_MinWidth,       60 + leftoff + rightoff,
  257.              WA_IDCMP,          CLOSEWINDOW | IDCMPUPDATE | NEWSIZE | MENUPICK | MOUSEMOVE,
  258.              WA_Height,         innerheight + topoff + bottomoff,
  259.              WA_Width,          innerwidth + leftoff + rightoff,
  260.              WA_Left,           winleft,
  261.              WA_Gadgets,        propgadget,
  262.              WA_Top,            wintop,
  263.              WA_Title,          "Lupe",
  264.              WA_PubScreen,      scr,
  265.              WA_Zoom,           &zoom,
  266.              TAG_DONE))
  267.             {
  268.                SetMenuStrip (mywin, menu);
  269.                userport = mywin->UserPort;
  270.                ScreenToFront (scr);
  271.                return TRUE;
  272.             }
  273.          }
  274.       }
  275.    }
  276.    return FALSE;
  277. }
  278.  
  279. void closewin ()
  280. {
  281.    ClearMenuStrip (mywin);
  282.    CloseWindow (mywin);
  283.    FreeMenus (menu);
  284.    DisposeObject (propgadget);
  285.    if (srcbm) FreeBitMap (srcbm);
  286.    if (destbm) FreeBitMap (destbm);
  287.    srcbm = NULL;
  288.    destbm = NULL;
  289. }
  290.  
  291. void refresh ()
  292. {
  293. LONG x, y;
  294.  
  295.    x = scr->MouseX - innerwidth / scalefac / 2;
  296.    y = scr->MouseY - innerheight / scalefac / 2;
  297.    if (x < 0) x = 0;
  298.    if (x > (scr->Width - innerwidth / scalefac))
  299.       x = scr->Width - innerwidth / scalefac;
  300.    if (y < 0) y = 0;
  301.    if (y > (scr->Height - innerheight / scalefac))
  302.       y = scr->Height - innerheight / scalefac;
  303.    BltBitMap (scrbm, x, y, srcbm, 0, 0, innerwidth / scalefac, innerheight / scalefac, ABNC | ABC, ~0, NULL);
  304.    WaitBlit ();
  305.    if (scalefac)
  306.    {
  307.       BitMapScale (&bsa);
  308.       WaitBlit ();
  309.       if ((winx == mywin->Width) && (winy == mywin->Height))
  310.          BltBitMapRastPort (destbm, 0, 0, mywin->RPort, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  311.    }
  312.    else BltBitMapRastPort (srcbm, 0, 0, mywin->RPort, leftoff, topoff, innerwidth, innerheight, ABNC | ABC);
  313.    WaitBlit ();
  314. }
  315.  
  316. void CxFunction (CxMsg *cxm, CxObj *co)
  317. {
  318. struct InputEvent *ie;
  319.  
  320.    ie = (struct InputEvent *) CxMsgData (cxm);
  321.    if ((ie->ie_Class == IECLASS_TIMER) || ((ie->ie_Class == IECLASS_RAWMOUSE) && mm))
  322.       Signal (thistask, 1 << timesig);
  323. }
  324.  
  325. BOOL initbroker ()
  326. {
  327.    if (broker_mp = CreateMsgPort ())
  328.    {
  329.       newbroker.nb_Port = broker_mp;
  330.       cxsigflag = 1L << broker_mp->mp_SigBit;
  331.       if (broker = CxBroker (&newbroker, NULL))
  332.       {
  333.          if (customcxobj = CxCustom (CxFunction, 0L))
  334.          {
  335.             if (!CxObjError (customcxobj))
  336.             {
  337.                AttachCxObj (broker, customcxobj);
  338.                ActivateCxObj (broker, 1L);
  339.                return TRUE;
  340.             }
  341.          }
  342.       }
  343.    }
  344.    return FALSE;
  345. }
  346.  
  347. void processmsg ()
  348. {
  349. struct IntuiMessage *intuimsg = NULL, m;
  350. CxMsg *msg;
  351. BOOL cont = TRUE;
  352. LONG sigmask, msgid, msgtype;;
  353. UWORD code;
  354. static BOOL (*func)();
  355.  
  356.    waitmask = (1 << userport->mp_SigBit) | (1 << timesig) | cxsigflag | SIGBREAKF_CTRL_C;
  357.    while (cont)
  358.    {
  359.       sigmask = Wait (waitmask);
  360.       if (sigmask & cxsigflag)
  361.       {
  362.          while (msg = (CxMsg *) GetMsg (broker_mp))
  363.          {
  364.             msgid = CxMsgID (msg);
  365.             msgtype = CxMsgType (msg);
  366.             ReplyMsg ((struct Message *) msg);
  367.             switch (msgtype)
  368.             {
  369.              case CXM_COMMAND:
  370.                switch (msgid)
  371.                {
  372.                 case CXCMD_DISABLE:
  373.                   ActivateCxObj (broker, 0L);
  374.                   break;
  375.                 case CXCMD_ENABLE:
  376.                   ActivateCxObj (broker, 1L);
  377.                   break;
  378.                 case CXCMD_UNIQUE:
  379.                 case CXCMD_KILL:
  380.                   cont = FALSE;
  381.                   break;
  382.                }
  383.             }
  384.          }
  385.       }
  386.       if (sigmask & (1 << userport->mp_SigBit))
  387.       {
  388.          jump = FALSE;
  389.          while (intuimsg = (struct IntuiMessage *) GetMsg (userport))
  390.          {
  391.             CopyMem ((char *) intuimsg, (char *) &m, (long) sizeof (struct IntuiMessage));
  392.             ReplyMsg ((struct Message *) intuimsg);
  393.             switch (m.Class)
  394.             {
  395.              case CLOSEWINDOW:
  396.                cont = FALSE;
  397.                break;
  398.              case NEWSIZE:
  399.                if (allocbm ()) cont = FALSE;
  400.                break;
  401.              case IDCMPUPDATE:
  402.                ULONG h;
  403.                GetAttr (PGA_Top, propgadget, &h);
  404.                if (++h != scalefac)
  405.                {
  406.                   scalefac = h;
  407.                   if (allocbm ()) cont = FALSE;
  408.                }
  409.                break;
  410.              case MENUPICK:
  411.                code = m.Code;
  412.                while ((code != MENUNULL) && cont && !jump)
  413.                {
  414.                   item = ItemAddress (menu, code);
  415.                   func = (BOOL (*)()) GTMENUITEM_USERDATA (item);
  416.                   cont = func ();
  417.                   if (!jump) code = item->NextSelect;
  418.                }
  419.                break;
  420.             }
  421.          }
  422.       }
  423.       if (sigmask & (1 << timesig))
  424.       {
  425.          refresh ();
  426.       }
  427.       if (sigmask & SIGBREAKF_CTRL_C)
  428.       {
  429.          cont = FALSE;
  430.       }
  431.    }
  432. }
  433.  
  434. BOOL mmFunc ()
  435. {
  436.    if ((mm == FALSE) && (item->Flags & CHECKED)) mm = TRUE;
  437.    else if (mm && !(item->Flags & CHECKED)) mm = FALSE;
  438.    return TRUE;   
  439. }
  440.  
  441. BOOL AboutFunc ()
  442. {
  443.    EasyRequestArgs (NULL, &es_about, NULL, era_about);
  444.    return TRUE;
  445. }
  446.  
  447. BOOL jumpFunc ()
  448. {
  449. int returnvalue;
  450.  
  451.    if (!(returnvalue = setupscreen ()))
  452.    {
  453.       waitmask &= ~(1 << userport->mp_SigBit);
  454.       wintop = mywin->TopEdge;
  455.       winleft = mywin->LeftEdge;
  456.       closewin ();
  457.       getoffsets ();
  458.       if (!openwin ()) return FALSE;
  459.       waitmask |= 1 << userport->mp_SigBit;
  460.       if (allocbm ()) return FALSE;
  461.       jump = TRUE;
  462.       return TRUE;
  463.    }
  464.    else if (returnvalue == 1) return TRUE;      // kein anderer Pubscreen
  465.    return FALSE;
  466. }
  467.  
  468. BOOL QuitFunc ()
  469. {
  470.    return FALSE;
  471. }
  472.  
  473. void main ()
  474. {
  475.    if (CxBase = OpenLibrary ("commodities.library", 37))
  476.    {
  477.       if (GfxBase = OpenLibrary ("graphics.library", 39))
  478.       {
  479.          if (GadToolsBase = OpenLibrary ("gadtools.library", 37))
  480.          {
  481.             if (!setupscreen ())
  482.             {
  483.                getoffsets ();
  484.                wintop = topoff;
  485.                if (scr->Height > 300) innerheight <<= 1;
  486.                if (openwin ())
  487.                {
  488.                   if (!allocbm ())
  489.                   {
  490.                      if ((timesig = AllocSignal (-1L)) != -1)
  491.                      {
  492.                         thistask = SysBase->ThisTask;
  493.                         if (initbroker ())
  494.                         {
  495.                            processmsg ();
  496.                            DeleteCxObjAll (broker);
  497.                         }
  498.                         FreeSignal (timesig);
  499.                      }
  500.                   } 
  501.                   closewin ();
  502.                }
  503.                CloseDownScreen ();
  504.             }
  505.             CloseLibrary (GadToolsBase);
  506.          }
  507.          CloseLibrary (GfxBase);
  508.       }
  509.       CloseLibrary (CxBase);
  510.    }
  511. }
  512.  
  513.